package com.rickpan.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.rickpan.dto.request.CreateWorkRecordRequest;
import com.rickpan.dto.request.UpdateWorkRecordRequest;
import com.rickpan.dto.response.WorkRecordResponse;
import com.rickpan.entity.WorkCategory;
import com.rickpan.entity.WorkRecord;
import com.rickpan.exception.BusinessException;
import com.rickpan.repository.WorkCategoryRepository;
import com.rickpan.repository.WorkRecordRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 工作记录服务类
 */
@Service
@Transactional
public class WorkRecordService {

    private static final Logger logger = LoggerFactory.getLogger(WorkRecordService.class);

    @Autowired
    private WorkRecordRepository workRecordRepository;

    @Autowired
    private WorkCategoryRepository workCategoryRepository;

    @Autowired
    private WorkCategoryService workCategoryService;

    @Autowired
    private ObjectMapper objectMapper;

    /**
     * 创建工作记录
     * @param userId 用户ID
     * @param request 创建请求
     * @return 创建的工作记录
     */
    public WorkRecordResponse createWorkRecord(Long userId, CreateWorkRecordRequest request) {
        logger.info("创建工作记录，用户ID: {}, 标题: {}", userId, request.getTitle());

        // 验证分类权限
        if (request.getCategoryId() != null && 
            !workCategoryService.isCategoryAccessible(userId, request.getCategoryId())) {
            throw new BusinessException("无权限使用此分类");
        }

        // 创建工作记录实体
        WorkRecord workRecord = new WorkRecord();
        workRecord.setUserId(userId);
        workRecord.setDate(request.getDate());
        workRecord.setTitle(request.getTitle());
        workRecord.setContent(request.getContent());
        workRecord.setCategoryId(request.getCategoryId());
        workRecord.setStatus(request.getStatus());
        workRecord.setPriority(request.getPriority());
        workRecord.setTimeSpent(request.getTimeSpent());

        // 处理标签
        if (request.getTags() != null && !request.getTags().isEmpty()) {
            try {
                // 确保标签列表正确序列化
                List<String> tagList = request.getTags();
                workRecord.setTags(objectMapper.writeValueAsString(tagList));
                logger.debug("标签序列化成功: {} -> {}", tagList, workRecord.getTags());
            } catch (JsonProcessingException e) {
                logger.warn("标签序列化失败: {}", e.getMessage());
                workRecord.setTags("[]");
            }
        } else {
            workRecord.setTags("[]");
        }

        WorkRecord savedRecord = workRecordRepository.save(workRecord);
        
        logger.info("工作记录创建成功，记录ID: {}", savedRecord.getId());
        return buildWorkRecordResponse(savedRecord);
    }

    /**
     * 更新工作记录
     * @param userId 用户ID
     * @param recordId 记录ID
     * @param request 更新请求
     * @return 更新后的工作记录
     */
    public WorkRecordResponse updateWorkRecord(Long userId, Long recordId, UpdateWorkRecordRequest request) {
        logger.info("更新工作记录，用户ID: {}, 记录ID: {}", userId, recordId);

        WorkRecord workRecord = workRecordRepository.findById(recordId)
                .orElseThrow(() -> new BusinessException("工作记录不存在"));

        // 检查权限
        if (!workRecord.getUserId().equals(userId)) {
            throw new BusinessException("无权限修改此工作记录");
        }

        // 验证分类权限
        if (request.getCategoryId() != null && 
            !workCategoryService.isCategoryAccessible(userId, request.getCategoryId())) {
            throw new BusinessException("无权限使用此分类");
        }

        // 更新字段
        if (request.getDate() != null) workRecord.setDate(request.getDate());
        if (request.getTitle() != null) workRecord.setTitle(request.getTitle());
        if (request.getContent() != null) workRecord.setContent(request.getContent());
        if (request.getCategoryId() != null) workRecord.setCategoryId(request.getCategoryId());
        if (request.getStatus() != null) workRecord.setStatus(request.getStatus());
        if (request.getPriority() != null) workRecord.setPriority(request.getPriority());
        if (request.getTimeSpent() != null) workRecord.setTimeSpent(request.getTimeSpent());

        // 处理标签
        if (request.getTags() != null) {
            try {
                // 确保标签列表正确序列化
                List<String> tagList = request.getTags();
                workRecord.setTags(objectMapper.writeValueAsString(tagList));
                logger.debug("标签更新成功: {} -> {}", tagList, workRecord.getTags());
            } catch (JsonProcessingException e) {
                logger.warn("标签序列化失败: {}", e.getMessage());
                workRecord.setTags("[]");
            }
        }

        WorkRecord savedRecord = workRecordRepository.save(workRecord);
        
        logger.info("工作记录更新成功，记录ID: {}", savedRecord.getId());
        return buildWorkRecordResponse(savedRecord);
    }

    /**
     * 删除工作记录
     * @param userId 用户ID
     * @param recordId 记录ID
     */
    public void deleteWorkRecord(Long userId, Long recordId) {
        logger.info("删除工作记录，用户ID: {}, 记录ID: {}", userId, recordId);

        WorkRecord workRecord = workRecordRepository.findById(recordId)
                .orElseThrow(() -> new BusinessException("工作记录不存在"));

        // 检查权限
        if (!workRecord.getUserId().equals(userId)) {
            throw new BusinessException("无权限删除此工作记录");
        }

        workRecordRepository.delete(workRecord);
        
        logger.info("工作记录删除成功，记录ID: {}", recordId);
    }

    /**
     * 获取工作记录详情
     * @param userId 用户ID
     * @param recordId 记录ID
     * @return 工作记录详情
     */
    @Transactional(readOnly = true)
    public WorkRecordResponse getWorkRecord(Long userId, Long recordId) {
        WorkRecord workRecord = workRecordRepository.findById(recordId)
                .orElseThrow(() -> new BusinessException("工作记录不存在"));

        // 检查权限
        if (!workRecord.getUserId().equals(userId)) {
            throw new BusinessException("无权限查看此工作记录");
        }

        return buildWorkRecordResponse(workRecord);
    }

    /**
     * 分页查询用户的工作记录
     * @param userId 用户ID
     * @param page 页码
     * @param size 页大小
     * @return 分页结果
     */
    @Transactional(readOnly = true)
    public Page<WorkRecordResponse> getUserWorkRecords(Long userId, int page, int size) {
        Pageable pageable = PageRequest.of(page, size);
        Page<WorkRecord> recordPage = workRecordRepository.findByUserIdOrderByDateDescCreatedAtDesc(userId, pageable);

        return recordPage.map(this::buildWorkRecordResponse);
    }

    /**
     * 分页查询用户的工作记录（带筛选）
     */
    @Transactional(readOnly = true)
    public Page<WorkRecordResponse> getUserWorkRecords(Long userId, int page, int size,
                                                      String keyword, Long categoryId, String status,
                                                      String priority, String startDate, String endDate) {
        Pageable pageable = PageRequest.of(page, size);

        // 构建查询条件
        LocalDate start = null;
        LocalDate end = null;

        if (startDate != null && !startDate.trim().isEmpty()) {
            try {
                start = LocalDate.parse(startDate);
            } catch (Exception e) {
                logger.warn("解析开始日期失败: {}", startDate);
            }
        }

        if (endDate != null && !endDate.trim().isEmpty()) {
            try {
                end = LocalDate.parse(endDate);
            } catch (Exception e) {
                logger.warn("解析结束日期失败: {}", endDate);
            }
        }

        WorkRecord.Status statusEnum = null;
        if (status != null && !status.trim().isEmpty()) {
            try {
                statusEnum = WorkRecord.Status.valueOf(status);
            } catch (Exception e) {
                logger.warn("解析状态失败: {}", status);
            }
        }

        WorkRecord.Priority priorityEnum = null;
        if (priority != null && !priority.trim().isEmpty()) {
            try {
                priorityEnum = WorkRecord.Priority.valueOf(priority);
            } catch (Exception e) {
                logger.warn("解析优先级失败: {}", priority);
            }
        }

        // 使用Repository的复合查询方法
        Page<WorkRecord> recordPage = workRecordRepository.findByComplexConditions(
            userId, keyword, categoryId, statusEnum, priorityEnum, start, end, pageable);

        return recordPage.map(this::buildWorkRecordResponse);
    }

    /**
     * 根据日期查询工作记录
     * @param userId 用户ID
     * @param date 日期
     * @return 工作记录列表
     */
    @Transactional(readOnly = true)
    public List<WorkRecordResponse> getWorkRecordsByDate(Long userId, LocalDate date) {
        List<WorkRecord> records = workRecordRepository.findByUserIdAndDateOrderByCreatedAtAsc(userId, date);
        
        return records.stream()
                .map(this::buildWorkRecordResponse)
                .collect(Collectors.toList());
    }

    /**
     * 根据日期范围查询工作记录
     * @param userId 用户ID
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 工作记录列表
     */
    @Transactional(readOnly = true)
    public List<WorkRecordResponse> getWorkRecordsByDateRange(Long userId, LocalDate startDate, LocalDate endDate) {
        List<WorkRecord> records = workRecordRepository.findByUserIdAndDateBetweenOrderByDateAscCreatedAtAsc(
                userId, startDate, endDate);
        
        return records.stream()
                .map(this::buildWorkRecordResponse)
                .collect(Collectors.toList());
    }

    /**
     * 构建工作记录响应对象
     * @param workRecord 工作记录实体
     * @return 响应对象
     */
    private WorkRecordResponse buildWorkRecordResponse(WorkRecord workRecord) {
        WorkRecordResponse response = new WorkRecordResponse(workRecord);
        
        // 填充分类信息
        if (workRecord.getCategoryId() != null) {
            try {
                WorkCategory category = workCategoryRepository.findById(workRecord.getCategoryId()).orElse(null);
                if (category != null) {
                    response.setCategoryName(category.getName());
                    response.setCategoryColor(category.getColor());
                    response.setCategoryIcon(category.getIcon());
                }
            } catch (Exception e) {
                logger.warn("获取分类信息失败: {}", e.getMessage());
            }
        }
        
        return response;
    }
}
